/**
 * useCallback 用于优化性能，返回一个记忆化的回调函数，可以减少不必要的重新渲染，也就是说它是用于缓存组件内的函数，避免函数的重复创建。
 * 总结
    1、useCallback的使用需要有所节制，不要盲目地对每个方法应用useCallback，这样做可能会导致不必要的性能损失。useCallback本身也需要一定的性能开销。
    2、useCallback并不是为了阻止函数的重新创建，而是通过依赖项来决定返回新的函数还是旧的函数，从而在依赖项不变的情况下确保函数的地址不变。
 */

import React, { useCallback, useState } from "react"

const funcMap = new WeakMap()
let counter = 1
export default function Demo09() {
  const [search, setSearch] = useState("")
  const changeSearch = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    setSearch(e.target.value)
  }, [])

  if (!funcMap.has(changeSearch)) {
    funcMap.set(changeSearch, counter++)
  }

  console.log(funcMap.get(changeSearch))

  const callback = useCallback(() => {
    console.log('按钮点击')
  }, [])
  return <>
    <h1>useCallback示例</h1>
    <h2>案例1</h2>
    <input type="text" value={search} onChange={changeSearch} />
    <h2>案例2</h2>
    <Child callback={callback} />
  </>
}

const Child = React.memo(({callback}: {callback: () => void}) => {
  // 如果callback是普通函数，那么子组件每次都会重新渲染
  // 如果callback是useCallback返回的函数，那么子组件只会渲染一次
  console.log('子组件渲染')
  return <>
    <div>子组件</div>
    <button onClick={callback}>按钮</button>
  </>
})